<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>语音合成与语音识别应用</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }

    body {
      background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
      color: #fff;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 2rem;
    }

    .container {
      max-width: 800px;
      width: 100%;
      background: rgba(255, 255, 255, 0.1);
      backdrop-filter: blur(10px);
      border-radius: 20px;
      padding: 2rem;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
      margin-top: 1rem;
    }

    header {
      text-align: center;
      margin-bottom: 2rem;
    }

    h1 {
      font-size: 2.5rem;
      margin-bottom: 0.5rem;
      text-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    }

    .subtitle {
      font-size: 1.2rem;
      opacity: 0.9;
    }

    .card {
      background: rgba(255, 255, 255, 0.15);
      border-radius: 15px;
      padding: 1.5rem;
      margin-bottom: 2rem;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    }

    h2 {
      font-size: 1.5rem;
      margin-bottom: 1rem;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    h2 i {
      font-size: 1.8rem;
    }

    .input-group {
      display: flex;
      margin-bottom: 1rem;
    }

    textarea {
      width: 100%;
      min-height: 120px;
      padding: 1rem;
      border: none;
      border-radius: 10px;
      background: rgba(255, 255, 255, 0.9);
      color: #333;
      font-size: 1rem;
      resize: vertical;
    }

    .buttons {
      display: flex;
      gap: 1rem;
      margin-top: 1rem;
      flex-wrap: wrap;
    }

    button {
      padding: 0.8rem 1.5rem;
      border: none;
      border-radius: 50px;
      background: #ff6b6b;
      color: white;
      font-size: 1rem;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.3s ease;
      display: flex;
      align-items: center;
      gap: 8px;
      box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    }

    button:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
    }

    button:active {
      transform: translateY(0);
    }

    #startListening {
      background: #4cd964;
    }

    #stopListening {
      background: #ff9500;
    }

    #speakText {
      background: #5ac8fa;
    }

    #clearText {
      background: #8e8e93;
    }

    .status {
      margin-top: 1rem;
      padding: 1rem;
      border-radius: 10px;
      background: rgba(255, 255, 255, 0.1);
      min-height: 60px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1.1rem;
    }

    .listening .status {
      background: rgba(76, 217, 100, 0.2);
      animation: pulse 1.5s infinite;
    }

    .speaking .status {
      background: rgba(90, 200, 250, 0.2);
      animation: pulse 1.5s infinite;
    }

    @keyframes pulse {
      0% { opacity: 1; }
      50% { opacity: 0.7; }
      100% { opacity: 1; }
    }

    .recognition-result {
      margin-top: 1rem;
      padding: 1rem;
      border-radius: 10px;
      background: rgba(255, 255, 255, 0.1);
      min-height: 80px;
    }

    .recognition-text {
      font-size: 1.1rem;
      line-height: 1.5;
    }

    .instructions {
      margin-top: 2rem;
      font-size: 0.9rem;
      opacity: 0.8;
      text-align: center;
      line-height: 1.5;
    }

    @media (max-width: 600px) {
      .container {
        padding: 1.5rem;
      }

      h1 {
        font-size: 2rem;
      }

      .buttons {
        flex-direction: column;
      }

      button {
        width: 100%;
        justify-content: center;
      }
    }
  </style>
</head>
<body>
<header>
  <h1>语音合成与语音识别</h1>
  <p class="subtitle">使用Web Speech API实现语音交互</p>
</header>

<div class="container">
  <div class="card">
    <h2><i>🔊</i> 语音合成</h2>
    <p>输入您想要转换为语音的文本：</p>
    <textarea id="textToSpeak" placeholder="在这里输入文本..."></textarea>
    <div class="buttons">
      <button id="speakText">
        <i>▶️</i> 朗读文本
      </button>
      <button id="clearText">
        <i>🗑️</i> 清空文本
      </button>
    </div>
  </div>

  <div class="card">
    <h2><i>🎤</i> 语音识别</h2>
    <p>点击下方按钮开始语音识别：</p>
    <div class="buttons">
      <button id="startListening">
        <i>🔴</i> 开始录音
      </button>
      <button id="stopListening" disabled>
        <i>⏹️</i> 停止录音
      </button>
    </div>
    <div class="status" id="recognitionStatus">
      准备就绪，点击"开始录音"按钮
    </div>
    <div class="recognition-result">
      <p class="recognition-text" id="recognitionResult">识别结果将显示在这里...</p>
    </div>
  </div>

  <div class="instructions">
    <p><strong>使用提示：</strong> 请确保您的设备有麦克风并已授权使用。语音识别功能在Chrome浏览器中效果最佳。</p>
  </div>
</div>

<script>
  // 检查浏览器是否支持Web Speech API
  if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
    alert('抱歉，您的浏览器不支持语音识别功能。请使用Chrome浏览器。');
  }

  if (!('speechSynthesis' in window)) {
    alert('抱歉，您的浏览器不支持语音合成功能。');
  }

  // 获取DOM元素
  const textToSpeak = document.getElementById('textToSpeak');
  const speakTextBtn = document.getElementById('speakText');
  const clearTextBtn = document.getElementById('clearText');
  const startListeningBtn = document.getElementById('startListening');
  const stopListeningBtn = document.getElementById('stopListening');
  const recognitionStatus = document.getElementById('recognitionStatus');
  const recognitionResult = document.getElementById('recognitionResult');
  const body = document.body;

  // 语音合成功能
  speakTextBtn.addEventListener('click', () => {
    const text = textToSpeak.value.trim();
    if (text === '') {
      alert('请输入要朗读的文本');
      return;
    }

    // 停止任何正在进行的语音
    window.speechSynthesis.cancel();

    // 创建语音合成实例
    const utterance = new SpeechSynthesisUtterance(text);

    // 设置语音参数
    utterance.rate = 0.9; // 语速
    utterance.pitch = 1;  // 音调
    utterance.volume = 1; // 音量

    // 选择中文语音（如果可用）
    const voices = window.speechSynthesis.getVoices();
    const chineseVoice = voices.find(voice => voice.lang.includes('zh'));
    if (chineseVoice) {
      utterance.voice = chineseVoice;
    }

    // 开始朗读
    window.speechSynthesis.speak(utterance);

    // 更新状态
    body.classList.add('speaking');
    recognitionStatus.textContent = '正在朗读文本...';

    // 朗读结束后的回调
    utterance.onend = () => {
      body.classList.remove('speaking');
      recognitionStatus.textContent = '朗读完成';
      setTimeout(() => {
        recognitionStatus.textContent = '准备就绪，点击"开始录音"按钮';
      }, 2000);
    };
  });

  // 清空文本功能
  clearTextBtn.addEventListener('click', () => {
    textToSpeak.value = '';
  });

  // 语音识别功能
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
  const recognition = new SpeechRecognition();

  // 设置识别参数
  recognition.continuous = true;
  recognition.interimResults = true;
  recognition.lang = 'en-US';

  // 开始识别
  startListeningBtn.addEventListener('click', () => {
    recognition.start();
    startListeningBtn.disabled = true;
    stopListeningBtn.disabled = false;
    body.classList.add('listening');
    recognitionStatus.textContent = '正在聆听...请说话';
  });

  // 停止识别
  stopListeningBtn.addEventListener('click', () => {
    recognition.stop();
    startListeningBtn.disabled = false;
    stopListeningBtn.disabled = true;
    body.classList.remove('listening');
    recognitionStatus.textContent = '识别结束';
  });

  // 识别结果处理
  recognition.onresult = (event) => {
    let finalTranscript = '';
    let interimTranscript = '';

    for (let i = event.resultIndex; i < event.results.length; i++) {
      const transcript = event.results[i][0].transcript;
      if (event.results[i].isFinal) {
        finalTranscript += transcript;
      } else {
        interimTranscript += transcript;
      }
    }

    // 显示识别结果
    recognitionResult.innerHTML = finalTranscript || interimTranscript;
  };

  // 识别错误处理
  recognition.onerror = (event) => {
    console.error('语音识别错误:', event.error);
    recognitionStatus.textContent = `识别错误: ${event.error}`;
    body.classList.remove('listening');
    startListeningBtn.disabled = false;
    stopListeningBtn.disabled = true;
  };

  // 识别结束处理
  recognition.onend = () => {
    body.classList.remove('listening');
    startListeningBtn.disabled = false;
    stopListeningBtn.disabled = true;
    recognitionStatus.textContent = '识别结束';
  };
</script>
</body>
</html>